from Clases.Memoria import Memoria
from Clases.Signal import Signal
from threading import Thread
import time

class CPU(Thread):
    
    def __init__(self, manager, mmu, planificador):
        Thread.__init__(self)
        self.pcb = None
        self.memory = mmu
        self.manager = manager
        self.planificador = planificador # Puede ser un FIFO , PRIORITY o un RR que
                                        #utiliza alguno de los 2 planificadores anteriores
     
    #getter#    
    def getPC(self):
        return self.pcb
    
    def setPC(self,pcNew):
        self.pcb = pcNew

    def seEjecutoInstruccion(self):
        self.planificador.instruccionEjecutada(self.manager)
    
    #Metodos#
    def run(self): 
            while self.manager.getKernel().getRUNNING(): 
                if  self.pcb is not None:
                    instruccion = self.memory.leer(self.pcb)
                    if instruccion is None: #el programa termino
                        print("ejecuta signal de q termino el programa")
                        self.manager.interrupt(Signal.EXIT) #interrupt exit
                    else: 
                        self.pcb.incrementarInstruccion() #no modifica el pcb nuevo en caso que la instruccion tenga que salir
                        print("ejecuta una instruccion")
                        self.ejecutarInstruccion(instruccion)
                        self.seEjecutoInstruccion()
                else: #si el pcb es vacio se duerme un rato
                    print("sleep 0.5")
                    time.sleep(0.5)


    def ejecutarInstruccion(self,instruccion):
        if instruccion.tipo is Signal.CPU:
            instruccion.execute()
        else:
            print("instruccion invalida!!!")
            self.manager.interrupt(Signal.EXIT) 